<script setup lang="ts">
import GenericOrgTree from "@/components/tree/tree";
import {h, nextTick, onMounted, reactive, ref, render, watch} from "vue";
import {
  ElInput,
  ElIcon,
  ElButton,
  ElDrawer,
  ElForm,
  ElFormItem,
  ElCheckboxGroup,
  ElRadioGroup,
  ElRadio,
  FormRules,
  ElMessage,
  ElMessageBox
} from "element-plus";
import {Search, Refresh, Close} from "@element-plus/icons-vue"
import {useDelGeofenceApi, useGeofenceAllApi, useGeofenceSaveApi} from "@/api/gps/enclosure";
import SelectOrgTree from "@/components/tree/selectTree";
import Menu, {ItemName} from "@/components/menu/enclosureMenu.vue";
import TreeNode from "@/components/tree/treeNode";
import {Geofence} from "@/interface/home";
import {cloneDeep} from "lodash";

const emits = defineEmits(["clearDraw", "close", "getDrawData", "createGeometry", "closeDraw",
  "drawEnclosure", "removeEnclosure", "selectEnclosure"])
const props = defineProps({
  enclosure: Object
})

const treeRef = ref()
const formRef = ref()
const searchKey = ref()
const drawer = ref(false)
const checkedCities = ref<string[]>([])

export interface Enclosure {
  id: string | undefined
  companyId: number | undefined
  name: string
  type: string
  icon: string
  area: string
}

const formData = reactive<Enclosure>({
  id: undefined,
  name: "",
  companyId: undefined,
  icon: "",
  type: "",
  area: ""
})


const rules = reactive<FormRules<Enclosure>>({
  name: { required: true, message: '必须填写名称', trigger: 'blur' },
  companyId: { required: true, message: '必须选择所属公司', trigger: 'blur' },
  type: { required: true, message: '必填项', trigger: 'blur' },
  area: { required: true, message: '必填项1', trigger: 'blur' },
})

let enclosureList: {[key: string]: Geofence}

onMounted(()=>{
  treeRef.value.init(useGeofenceAllApi()).then(res =>{
    const data = res[0].data
    enclosureList = {}
    data.forEach(item =>{
      const newData = {nodeId: item.id, nodeType: "geofence", ...item}
      enclosureList[item.id] = newData
      treeRef.value.append(newData, "i-" + item.companyId)
    })
  })
})

let needToRepaint = false
watch(drawer, (val)=>{
  if (!formData.id) return
  const index = checkedCities.value.indexOf(formData.id)
  if (val) {
    if (index > -1) {
      needToRepaint = index > -1
      checkedCities.value.splice(index, 1);
      handleCheckChange(enclosureList[formData.id], false)
    }
  } else {
    if (index === -1 && needToRepaint) {
      checkedCities.value.push(formData.id);
      handleCheckChange(enclosureList[formData.id], true)
      needToRepaint = false
    }
  }
})

/**
 * 右键菜单
 * @param event
 * @param data
 */
function contextmenu(event, data){
  console.log(event.target, data)
  const el = event.target
  if (el!.className === 'custom-tree-node') {
    let menuGroups: ItemName[] = []
    switch (el.getAttribute('data-types')){
      case "geofence":
        menuGroups = ["modifyTheFence", "removeFences", "fenceSettings"]
        break
      case "company":
        menuGroups = ["select", "selectDeep", "addedFences"]
        break
    }
    render(
        h(Menu, {
          style: `left: ${event.clientX}px; top: ${event.clientY}px`,
          imei: el.getAttribute('data-imei'),
          onModifyTheFence: () => modifyTheFence(data),
          onAddedFences: () => addedFences(data.id),
          onRemoveFences: () => removeEnclosure(data.id),
          menuGroups
        }),
        document.body
    )
    document.addEventListener('click', callback)
    function callback(event: any) {
      const menu = document.getElementById('right_click_menu')
      if (menu) {
        render(null, document.body)
      }
      document.removeEventListener('click', callback)
    }
  }
}
let timer
let arr: Geofence[] = []
/**
 * 围栏的勾选事件
 */
function handleCheckChange(data: Geofence, checked: boolean){
  console.log(data, checked)
  if(checked){
    arr.push(data)
    if (!timer) {
      timer = setTimeout(() => {
        emits("drawEnclosure", arr)
        timer =  null
        arr = []
      }, 100)
    }
  }else {
    emits("removeEnclosure", data.nodeId)
  }
}

/**
 * 编辑围栏
 * @param id
 * @param companyId
 * @param name
 * @param type
 * @param area
 */
function modifyTheFence({id, companyId, name, type, area}){
  formData.id = id
  formData.companyId = companyId
  formData.name = name
  formData.type = type
  emits("createGeometry", {
    id,
    type,
    data: area
  })
  drawer.value = true
}

/**
 * 指定公司新增围栏
 * @param id
 */
function addedFences(id: number){
  resetData()
  formData.companyId = id
  drawer.value = true
}

/**
 * 新增围栏
 */
function openDrawEnclosureWindow(){
  resetData()
  drawer.value = true
}

/**
 * 删除围栏
 */
function removeEnclosure(id){
  ElMessageBox.confirm(
      '确定要删除该数据该吗？请选择是否要继续',
      '警告',
      {
        confirmButtonText: '继续',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(() => {
        useDelGeofenceApi(id).then(()=>{
          ElMessage({
            type: 'success',
            message: '删除成功',
          })
          let index = checkedCities.value.indexOf(id); // 获取要删除元素的索引
          if (index > -1) {
            checkedCities.value.splice(index, 1); // 从数组中删除该元素
            handleCheckChange(enclosureList[id], false)
          }
          removeNode(id)
        })
      })
}

/**
 * 关闭围栏窗口
 */
function closeWindow(){
  emits("close")
}

/**
 * 关闭绘制窗口
 */
function closeDrawEnclosureWindow(){
  drawer.value = false
  emits("closeDraw")
}

/**
 * 提交
 */
function submit(){
  emits("getDrawData")
  let data
  nextTick(()=>{
    formRef.value.validate((valid, fields) =>{
      if (valid) {
        const item = props.enclosure?.[0]
        const geometry = item.getGeometry()
        switch (geometry.getType()){
          case "Circle":
            console.log(geometry.getCoordinates());
            data = {
              center: geometry.getCenter(),
              radius: geometry.getRadius()
            }
            break
          case "Polygon":
            console.log(geometry.getCoordinates());
            data = {
              coordinates: geometry.getCoordinates()
            }
            break
        }
        formData.area = JSON.stringify(data)
        useGeofenceSaveApi(formData).then(res =>{
          ElMessage.success("操作成功！")
          closeDrawEnclosureWindow()
          if(res.data){
            insetNode(res.data)
          }
        })
      } else {
        console.log('error submit!', fields)
      }
    })
  })
}

/**
 * 重置数据
 */
function resetData(){
  formData.companyId = undefined
  formData.id = undefined
  formData.name = ""
  formData.icon = ""
  formData.type = ""
  formData.area = ""
}

/**
 * 图形类型改变
 * @param val
 */
function drawChange(val){
  console.log(val)
  formData.icon = val
  emits("clearDraw", val)
}

/**
 * 插入节点
 * @param id
 */
function insetNode(id: string){
  const data: any = cloneDeep(formData)
  data.id = id
  data.nodeId = id
  data.nodeType = "geofence"
  treeRef.value.append(data, "i-" + data.companyId)
}

/**
 * 删除节点
 * @param nodeId
 */
function removeNode(nodeId: string){
  treeRef.value.remove(nodeId)
}

function handleNodeClick(data: Geofence){
  if(data.nodeType !== "geofence") return
  let index = checkedCities.value.indexOf(data.nodeId);
  if(index === -1){
    checkedCities.value.push(data.nodeId)
    handleCheckChange(enclosureList[data.nodeId], true)
  }
  setTimeout(()=>{
    emits("selectEnclosure", data.nodeId)
  }, 100)
}
</script>

<template>
  <div class="page">
    <div class="head">
      <div class="head_left">
        <p class="title">围栏管理</p>
        <ElButton type="primary" plain size="small"
                  style="transform: translateY(1px)"
                  @click="openDrawEnclosureWindow">新增围栏</ElButton>
      </div>
      <div class="popup_close" @click="closeWindow">
        <ElIcon size="20"><Close/></ElIcon>
      </div>
    </div>
    <ElInput v-model="searchKey" :prefix-icon="Search" size="small">
      <template #append>
        <ElButton size="small">
          <ElIcon><Refresh /></ElIcon>
        </ElButton>
      </template>
    </ElInput>
    <ElCheckboxGroup v-model="checkedCities">
      <GenericOrgTree ref="treeRef"
                      style="margin-top: 10px"
                      :props="{label: 'name',children: 'children'}"
                      node-key="nodeId"
                      @node-contextmenu="contextmenu"
                      @node-click="handleNodeClick">
        <template #default="{ node, data }">
          <TreeNode :data="data" @checkboxEvents="handleCheckChange"></TreeNode>
        </template>
      </GenericOrgTree>
    </ElCheckboxGroup>
    <ElDrawer
        v-model="drawer"
        :size="400"
        :with-header="false"
        direction="btt"
        show-close
    >
      <ElForm ref="formRef" :model="formData" :rules="rules" size="small" >
        <ElFormItem label="所属分组" prop="companyId">
          <SelectOrgTree v-model="formData.companyId"
                         :props="{label: 'name',children: 'children', value: 'id'}"
                         node-key="nodeId"
                         placeholder="请选择所属账号"
                         automatic></SelectOrgTree>
        </ElFormItem>
        <ElFormItem label="围栏名称" prop="name">
          <ElInput v-model="formData.name"></ElInput>
        </ElFormItem>
        <ElFormItem prop="type">
          <ElRadioGroup v-model="formData.type" class="custom" @change="drawChange">
            <ElRadio value="Circle" border>圆形</ElRadio>
            <ElRadio value="Polygon" border>多边形</ElRadio>
            <ElRadio value="LineString" border>路线</ElRadio>
          </ElRadioGroup>
        </ElFormItem>
        <ElFormItem>
          <ElButton type="danger" @click="closeDrawEnclosureWindow">取消</ElButton>
          <ElButton type="primary" @click="submit">保存</ElButton>
        </ElFormItem>
      </ElForm>
    </ElDrawer>
  </div>
</template>

<style scoped lang="scss">
.head{
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.head .title{
  font-size: 18px;
  margin-right: 15px;
}
.head_left{
  display: flex;
}

.page{
  padding: 5px 10px 10px 10px;
  position: relative;
}
.search{
  display: flex;
}
.drawer{
  position: absolute;
}
.custom{
  width: 100%;
}
.custom > label{
  margin-right: 10px;
  width: 76px;
}
.custom > label:nth-child(n+3){
  margin-top: 5px;
}
</style>